package com.wqz.tacos.impl;

import com.wqz.tacos.data.TacoRepository;
import com.wqz.tacos.models.Ingredient;
import com.wqz.tacos.models.Taco;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementCreatorFactory;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import java.sql.Timestamp;
import java.sql.Types;
import java.util.Arrays;
import java.util.Date;

@Repository
public class JdbcTacoRepository implements TacoRepository {
    private JdbcTemplate jdbc;

    public JdbcTacoRepository(JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }


    /**
     * 保存taco的时候需要将taco关联的配料表保存到taco_repository表中
     * 涉及到外键的保存以及主从关系的修改
     * @param design
     * @return
     */
    @Override
    public Taco save(Taco design) {
        long tacoId = saveTacoInfo(design);
        design.setId(tacoId);

        for(Ingredient ingredient : design.getIngredients()) {
            saveIngredientToTaco(ingredient, tacoId);
        }

        return design;
    }

    /**
     * 先保存taco的信息，然后获取数据库的对应的taco的Id，作为外表的外键
     * 有了Id之后在轮询Ingredient，逐个保存到taco_ingredients表中
     * @param taco
     * @return
     */
    private long saveTacoInfo(Taco taco) {
        // 保存创建时间
        taco.setCreateTime(new Date());
        PreparedStatementCreator psc = new PreparedStatementCreatorFactory(
                "insert into Taco (name, createTime) values ( ?, ?)",
                Types.VARCHAR, Types.TIMESTAMP
        ).newPreparedStatementCreator(
                Arrays.asList(
                        taco.getName(),
                        new Timestamp(taco.getCreateTime().getTime())
                )
        );

        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbc.update(psc, keyHolder);

        return keyHolder.getKey().longValue();
    }

    /**
     * 将每个taco的ingredients保存到Taco_Ingredients表中
     * @param ingredient
     * @param tacoId
     */
    private void saveIngredientToTaco(Ingredient ingredient, long tacoId) {
        this.jdbc.update("insert into Taco_Ingredients (taco, ingredient) " + "values (?, ? )",tacoId, ingredient.getId());
    }
}
